package cn.yujian95.hospital.service.impl;

import cn.yujian95.hospital.dto.param.VisitProductParam;
import cn.yujian95.hospital.dto.param.VisitProductParamDto;
import cn.yujian95.hospital.dto.update.VisitProductInfo;
import cn.yujian95.hospital.entity.*;
import cn.yujian95.hospital.mapper.HospitalProductMapper;
import cn.yujian95.hospital.mapper.UserBasicInfoMapper;
import cn.yujian95.hospital.mapper.VisitProductMapper;
import cn.yujian95.hospital.service.IVisitProductService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class VisitProductServiceImpl extends ServiceImpl<VisitProductMapper, VisitProduct> implements IVisitProductService {


    @Resource
    private VisitProductMapper visitProductMapper;

    @Resource
    private HospitalProductMapper hospitalProductMapper;

    @Resource
    private UserBasicInfoMapper userBasicInfoMapper;

    /**
     * 判断这个产品是否存在
     *
     * @param productId
     * @return
     */
    @Override
    public boolean countProductId(Long productId) {
        HospitalProduct hospitalProduct = hospitalProductMapper.selectById(productId);
        return hospitalProduct != null;
    }

    /**
     * 添加预约产品信息
     *
     * @param param
     * @return
     */
    @Override
    public String insert(VisitProductParam param) {

        // 先判断是否预约过这个产品
        // 如果预约了过了直接返回
        Long userId = param.getUserId();
        Long productId = param.getProductId();
        LambdaQueryWrapper<VisitProduct> visitProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
        visitProductLambdaQueryWrapper.eq(VisitProduct::getUserId, userId);
        visitProductLambdaQueryWrapper.eq(VisitProduct::getProductId, productId);
        // 你预约了但是没有去买东西，就不能在预约了
        visitProductLambdaQueryWrapper.eq(VisitProduct::getOk, 0);

        // 0表示他预约了但是没有去买东西，就不能在预约了
        VisitProduct one = getOne(visitProductLambdaQueryWrapper);
        if (one != null) {
            return "1";
        }

        VisitProduct visitProduct = new VisitProduct();

        BeanUtils.copyProperties(param, visitProduct);
        visitProduct.setOk(0); // 最开始都是只是预约了

        return save(visitProduct) ? "0" : "2";
    }

    /**
     * 查看和这个预约编号是否存在
     *
     * @param id
     * @return
     */
    @Override
    public boolean countId(Long id) {
        VisitProduct visitProduct = getById(id);
        return visitProduct != null;
    }

    /**
     * 删除预约产品的信息
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteAppointmentProduct(Long id) {
        return removeById(id);
    }

    /**
     * 完成预约产品详细信息
     *
     * @param id
     * @return
     */
    @Override
    public boolean AppointmentProductOk(Long id) {

        VisitProduct visitProduct = getById(id);
        // 已经处理过了
        if (visitProduct.getOk() == 1) {
            return true;
        }
        visitProduct.setOk(1);
        return updateById(visitProduct);
    }

    /**
     * 查询预约产品信息
     *
     * @param id
     * @return
     */
    @Override
    public VisitProductInfo getAppointmentProductInfo(Long id) {
        VisitProduct visitProduct = getById(id);
        Long productId = visitProduct.getProductId();
        Long userId = visitProduct.getUserId();

        VisitProductInfo visitProductInfo = new VisitProductInfo();


        // 首先是获得产品信息
        HospitalProduct hospitalProduct = hospitalProductMapper.selectById(productId);
        BeanUtils.copyProperties(hospitalProduct, visitProductInfo);
        visitProductInfo.setProductName(hospitalProduct.getName());

        // 其次获得用户信息
        UserBasicInfo userBasicInfo = userBasicInfoMapper.selectByPrimaryKey(userId);
        BeanUtils.copyProperties(userBasicInfo, visitProductInfo);

        // 预约的时间
        Date gmtCreate = visitProduct.getGmtCreate();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(gmtCreate);
        visitProductInfo.setGmtCreate(format);
        visitProductInfo.setId(id);

        return visitProductInfo;
    }

    /**
     * 分页查询产品信息
     *
     * @param productName
     * @param userName
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public IPage<VisitProductParamDto> list(String productName, String userName, Integer pageNum, Integer pageSize) {

        IPage<VisitProductParamDto> dtoIPage = new Page<>(pageNum, pageSize);

        IPage<VisitProduct> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<VisitProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        IPage<VisitProduct> page1 = page(page, lambdaQueryWrapper);

        List<VisitProduct> records = page1.getRecords();
        if (records == null) {
            BeanUtils.copyProperties(page1, dtoIPage);
            return dtoIPage;
        }


        // 给里面每一个进行赋值records

        // 最后要返回的前一个
        List<VisitProductParamDto> collect = records.stream().map(item -> {
            VisitProductParamDto visitProductParamDto = new VisitProductParamDto();
            BeanUtils.copyProperties(item, visitProductParamDto);
            return visitProductParamDto;
        }).collect(Collectors.toList());


        // 得到每一个产品
        // 如果没有产品了表示原来是有的，但是删除了
        List<HospitalProduct> hospitalProducts = hospitalProductMapper.selectList(null);


        // 得到每一个用户
        UserBasicInfoExample userBasicInfoExample = new UserBasicInfoExample();
        List<UserBasicInfo> userBasicInfos = userBasicInfoMapper.selectByExample(userBasicInfoExample);

        collect.forEach(item -> {
            if (hospitalProducts != null) {
                // 得到产品信息
                for (HospitalProduct i1 : hospitalProducts) {
                    if (Objects.equals(item.getProductId(), i1.getId())) {
                        item.setProductName(i1.getName());
                        item.setPrice(i1.getPrice());
                        item.setDescription(i1.getDescription());
                        break;
                    }

                }
            }
            if (userBasicInfos != null) {
                //
                for (UserBasicInfo u1 : userBasicInfos) {
                    if (Objects.equals(item.getUserId(), u1.getId())) {
                        item.setUserName(u1.getName());
                        break;
                    }
                }
            }
        });

        // 这个collect是收集到的
        // 下面开始条件查询
        LambdaQueryWrapper<HospitalProduct> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();


        if (!"".equals(productName)) {
            lambdaQueryWrapper1.like(HospitalProduct::getName, productName);

            List<HospitalProduct> hospitalProducts1 = hospitalProductMapper.selectList(lambdaQueryWrapper1);
            // 得到所有的id
            if (hospitalProducts1 != null) {
                // 返回产品id
                List<Long> longStream = hospitalProducts1.stream().map(HospitalProduct::getId).collect(Collectors.toList());
                collect = collect.stream().filter(item -> {
                    // 返回包含的
                    return longStream.contains(item.getProductId());
                }).collect(Collectors.toList());
            }
        }

        UserBasicInfoExample.Criteria basicInfoExampleCriteria = userBasicInfoExample.createCriteria();
        if (!"".equals(userName)) {
            basicInfoExampleCriteria.andNameLike(userName);
            List<UserBasicInfo> userBasicInfos1 = userBasicInfoMapper.selectByExample(userBasicInfoExample);
            if (userBasicInfos1 != null) {
                List<Long> collected = userBasicInfos1.stream().map(UserBasicInfo::getId).collect(Collectors.toList());
                collect = collect.stream().filter(item -> {
                    // 返回包含的
                    return collected.contains(item.getUserId());
                }).collect(Collectors.toList());
            }
        }
        dtoIPage.setTotal(collect.size());
        dtoIPage.setRecords(collect);
        return dtoIPage;
    }

    /**
     * 获取预约列表信息小程序端
     *
     * @param userId
     * @return
     */
    @Override
    public IPage<VisitProductParamDto> getAppointmentListProductInfoByUserId(Long userId) {
        IPage<VisitProductParamDto> dtoIPage = new Page<>(1, 100);
        IPage<VisitProduct> page = new Page<>(1, 100);
        LambdaQueryWrapper<VisitProduct> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 降序排序
        lambdaQueryWrapper.orderByDesc(VisitProduct::getGmtCreate);
        lambdaQueryWrapper.eq(VisitProduct::getUserId, userId);
        page = page(page, lambdaQueryWrapper);

        List<VisitProduct> records = page.getRecords();
        BeanUtils.copyProperties(page, dtoIPage);
        if (records == null) {
            // 表示没有预约信息
            return dtoIPage;
        }

        List<VisitProductParamDto> collect = records.stream().map(item -> {
            VisitProductParamDto visitProductParamDto = new VisitProductParamDto();
            BeanUtils.copyProperties(item, visitProductParamDto);
            return visitProductParamDto;
        }).collect(Collectors.toList());

        // 下面开始赋值
        // 给上产品信息以及
        // 得到每一个产品
        // 如果没有产品了表示原来是有的，但是删除了
        List<HospitalProduct> hospitalProducts = hospitalProductMapper.selectList(null);


        // 有预约记录的话
        collect.forEach(item -> {
            if (hospitalProducts != null) {
                // 得到产品信息
                for (HospitalProduct i1 : hospitalProducts) {
                    if (Objects.equals(item.getProductId(), i1.getId())) {
                        item.setProductName(i1.getName());
                        item.setPrice(i1.getPrice());
                        item.setDescription(i1.getDescription());
                        break;
                    }

                }
            }
        });
        dtoIPage.setRecords(collect);
        return dtoIPage;
    }


}
